package com.xiaoyu.lanling.feature.voicematch.util

import `in`.srain.cube.util.UriUtil
import android.annotation.TargetApi
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.utils.RxUtils
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.common.Constant
import com.xiaoyu.lanling.data.NotificationData
import com.xiaoyu.lanling.data.NotificationData.VIBRATE_PATTERN
import com.xiaoyu.lanling.feature.voicematch.service.VoiceMatchCallService
import com.xiaoyu.lanling.router.Router
import com.xiaoyu.lib_av.datamodel.CallParams
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit

class VoiceMatchNotificationUtils private constructor() {

    private var mCallServiceIntent: Intent? = null
    private var dismissable = false
    private var delay: Disposable? = null

    fun setDismissable(dismissable: Boolean) {
        this.dismissable = dismissable
    }

    fun buildNotification(title: CharSequence?, text: CharSequence?, pendingIntent: PendingIntent?): Notification {
        return NotificationCompat.Builder(AppContext.getContext(), NotificationData.ChannelId.CALL_VOICE_MATCH)
                .setContentTitle(title)
                .setContentText(text)
                .setContentIntent(pendingIntent)
                .setSound(UriUtil.parseResourceId(AppContext.getContext(), R.raw.raw_voice_match_success))
                .setVibrate(VIBRATE_PATTERN)
                .setTicker(text)
                .setWhen(System.currentTimeMillis())
                .setDefaults(Notification.DEFAULT_ALL)
                .setSmallIcon(R.drawable.mipush_small_notification)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true)
                .build()
    }

    fun showVoiceMatchNotification(callParams: CallParams, isCaller: Boolean, isReceive: Boolean) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            dismissable = false
            startVoiceMatchCallService(isCaller, isReceive, callParams)
            RxUtils.disposable(delay)
            delay = Observable.timer(6, TimeUnit.SECONDS)
                    .subscribe {
                        dismissable = true
                    }
        } else {
            showCallNotificationBelowApi26(isCaller, isReceive, callParams)
        }
    }

    fun dismissCallNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (dismissable) {
                stopVoiceMatchCallService()
            }
        } else {
            dismissCallNotificationBelowApi26()
        }
    }

    private fun showCallNotificationBelowApi26(isCaller: Boolean, isReceive: Boolean, callParams: CallParams) {
        val context = AppContext.getContext()
        val intent = Router.instance.createVoiceMatchCallVoiceIntent(context, callParams, isCaller)
        val text = getNotificationText(isReceive)
        val title = context.getString(R.string.voice_match_notification_title)
        val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        showVoiceMatchCallNotificationBase(title, text, pendingIntent)
    }

    private fun createVoiceMatchCallServiceIntent(isCaller: Boolean, isReceive: Boolean, callParams: CallParams): Intent {
        val intent = Intent(AppContext.getContext(), VoiceMatchCallService::class.java)
        intent.putExtra(Constant.IntentKey.KEY_CHAT_CALL_CALL_PARAM, callParams)
        intent.putExtra(Constant.IntentKey.KEY_CHAT_CALL_IS_CALLER, isCaller)
        return intent
    }

    private fun showVoiceMatchCallNotificationBase(title: CharSequence, text: CharSequence, pendingIntent: PendingIntent) {
        dismissCallNotificationBelowApi26()
        val notification = buildNotification(title, text, pendingIntent)
        notification.flags = Notification.FLAG_ONGOING_EVENT or Notification.FLAG_NO_CLEAR
        val notificationManager = AppContext.getContext().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(NotificationData.ChannelTag.CALL_VOICE_MATCH, NotificationData.NotificationId.CALL_VOICE_MATCH, notification)
    }

    private fun dismissCallNotificationBelowApi26() {
        try {
            val notificationManager = AppContext.getContext().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.cancel(NotificationData.ChannelTag.CALL_VOICE_MATCH, NotificationData.NotificationId.CALL_VOICE_MATCH)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @TargetApi(Build.VERSION_CODES.O)
    private fun startVoiceMatchCallService(isCaller: Boolean, isReceive: Boolean, callParams: CallParams) {
        mCallServiceIntent = instance.createVoiceMatchCallServiceIntent(isCaller, isReceive, callParams)
        AppContext.getContext().startForegroundService(mCallServiceIntent)
    }

    @TargetApi(Build.VERSION_CODES.O)
    private fun stopVoiceMatchCallService() {
        if (mCallServiceIntent == null) {
            return
        }
        AppContext.getContext().stopService(mCallServiceIntent)
    }

    companion object {
        val instance = VoiceMatchNotificationUtils()

        fun getNotificationText(isReceive: Boolean): CharSequence {
            return if (isReceive) AppContext.getString(R.string.voice_match_notification_received_text) else AppContext.getString(R.string.voice_match_notification_text)
        }
    }
}